import url from 'url';
import * as validation from '../../../common/validation';
import joiOmit from '../../helpers/joiOmit';

const baseChecker = (taskType, { settings, balance }) => {
	if (!balance.feature[`${taskType}Task`]) {
		settings.enable = false;
	}

	const balanceLimit = balance.balance?.[`${taskType}MaxFreq`]?.total || 0;
	if (settings.interval < balanceLimit) {
		settings.interval = balanceLimit;
	}
	const maxDepth = balance.balance?.[`${taskType}MaxDepth`]?.total || 0;
	if (settings.collect?.depth > maxDepth) {
		settings.collect.depth = maxDepth;
	}
};

const checker = [
	{
		// 漏洞监测频率
		ensure: x => x.vulSettings,
		validate({ value, balance }) {
			const settings = value.vulSettings;
			if (!settings) return;

			baseChecker('vul', { settings, balance });
		},
	},
	{
		// 安全事件监测频率
		ensure: x => x.securityEventSettings,
		validate({ value, balance }) {
			const taskType = 'securityEvent';

			const settings = value?.[`${taskType}Settings`];
			if (!settings) return;

			baseChecker(taskType, { settings, balance });
		},
	},
	{
		// 内容合规监测
		ensure: x => x.contentSettings,
		validate({ value, balance }) {
			const taskType = 'content';

			const settings = value?.[`${taskType}Settings`];
			if (!settings) return;

			baseChecker(taskType, { settings, balance });
		},
	},
	{
		// SSL监测频率
		ensure: x => x.sslSettings,
		validate({ value, balance }) {
			const taskType = 'ssl';

			const settings = value?.[`${taskType}Settings`];
			if (!settings) return;

			baseChecker(taskType, { settings, balance });
		},
	},
	{
		// 可用性任务
		ensure: x => x.pingSettings || x.httpSettings,
		validate({ value, balance }) {
			['http', 'ping'].forEach(taskType => {
				const settings = value[`${taskType}Settings`];
				if (!settings) return;

				const maxNode = balance.balance[`${taskType}MaxNode`];
				settings.forEach(s => {
					baseChecker(taskType, { settings: s, balance });

					// 最多监测节点数
					if (maxNode) {
						s.collect.area = s.collect.area.slice(0, maxNode.total);
					}
				});
			});

			// 监测任务的target使用外层的target的protocol和host
			if (value.target) {
				const target = new URL(url.format(value.target));
				[].concat(value.httpSettings).forEach(s => {
					target.pathname = new URL(s.target).pathname;
					s.target = target.toString();
				});
				[].concat(value.pingSettings).forEach(s => {
					target.pathname = new URL(s.target).pathname;
					s.target = target.toString();
				});
			}
		},
	},
];

export function validate(checker, validator, { record, balance }) {
	checker.forEach(({ ensure, validate }) => {
		if (!ensure(record)) return;
		validate({ balance, value: record });
	});

	const { value, error } = joiOmit(validator, {
		required: true,
		defualt: true,
	}).validate(record);
	if (error) throw new Error(error.message);

	return value;
}

export default function balanceValidate({ record, balance }) {
	return validate(checker, validation.job, { record, balance });
}

export function assetValidate({ record, balance }) {
	return validate(
		[
			{
				// 漏洞监测频率
				ensure: x => x.taskSettings,
				validate({ value, balance }) {
					const settings = value.taskSettings;
					if (!settings) return;

					const balanceLimit = balance.balance?.assetMaxFreq?.total || 0;
					if (settings.interval < balanceLimit) {
						settings.interval = balanceLimit;
					}
				},
			},
		],
		validation.asset,
		{ record, balance }
	);
}
